Skip to content

eXtremeDB ARM 构建失败排查 ​

在 ARM64 目标机上解压 eXtremeDB 发行包后直接 make 会失败,报错指向示例工程的 DDL 产物。本文记录一次完整的定位过程:从报错确认发行包自带的工具链架构不匹配,到中途尝试「升级系统 glibc」走入的弯路,最后回到在 x86_64 主机上交叉编译的正解。核心教训有两条:发行包里的 host 工具和目标机架构要分清;系统的 libc 软链接不能动。

现象 ​

解压 extremedb_8.3_fusion_linux_arm64_eval.tar.gz(eXtremeDB 8.3 评估版,ARM64 目标平台)后,在根目录运行 make 报错:

bash
make: *** [/home/user/eXtremeDB/include/rules.makefile:717: /home/user/eXtremeDB/samples/native/core/00-ddl/obj-00-ddl-Linux-arm64-exec-offs-ndbg/sampleddl.h] Error 2

目标机环境:ARM64 开发板,Ubuntu 20.04,gcc 9.4.0,glibc 2.31。

定位过程 ​

第一步:报错源头是 DDL 编译器 ​

按文档先单独跑 DDL 编译器验证:

bash
# ../../host/bin/mcocomp mydb.mco
bash: ../../host/bin/mcocomp: cannot execute binary file: Exec format error

mcocomp 是 eXtremeDB 的 DDL 模式编译器(McObject 官方文档明确此角色):把 .mco 模式定义文件编译成数据库字典和接口代码。Exec format error 说明这个二进制的架构与当前机器不符——评估包虽然面向 arm64 目标平台,附带的 host 工具却是 x86_64 版本的,无法在 ARM 主机上运行。

第二步:换 ARM 版工具,报错变为 glibc 版本不满足 ​

从厂商获取 ARM 平台的 mcocomp 替换后再跑,报错变成:

bash
../../host/bin/mcocomp: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ../../host/bin/mcocomp)

GLIBC_x.y not found 的含义是确定的:这个二进制要求 glibc 2.34 引入的符号版本,而 Ubuntu 20.04 的系统 glibc 是 2.31。确认一下系统提供的版本上限:

bash
# strings /lib/aarch64-linux-gnu/libc.so.6 | grep GLIBC_
GLIBC_2.17
GLIBC_2.18
...
GLIBC_2.30

确实没有 2.34。此时正确的方向其实已经清楚了(后面会说),但当时先走了另一条路。

第三步:弯路——替换系统 glibc ​

尝试在用户目录源码编译 glibc 2.34(--prefix=$HOME/glibc/glibc-2.34-install,configure 阶段需补装 gawk、bison 两个依赖),编译安装本身成功。接着把系统 libc 的软链接指了过去:

bash
# cp -d /lib/aarch64-linux-gnu/libc.so.6 /lib/aarch64-linux-gnu/libc.so.6.bak
# ln -sf $HOME/glibc/glibc-2.34-install/lib/libc.so.6 /lib/aarch64-linux-gnu/libc.so.6
# ll /lib/aarch64-linux-gnu/libc.so.6.bak
Segmentation fault

替换之后,ll 这样的基础命令立即段错误,只能靠备份恢复软链接。原因不难理解:系统里几乎所有动态链接程序都依赖 /lib 下的 libc,用手工商定时、与前缀不配套的 glibc 顶替系统版本,等于让所有进程依赖一个未经验证的 libc 实现。用户态前缀安装的高版本 glibc 可以保留,但只能按进程配合指定动态链接器与库搜索路径来用,不能通过修改系统软链接全局生效。

正确解法:回主机交叉编译 ​

回头看清问题本质:eXtremeDB 的构建模型本来就是「host 编译、target 运行」——DDL 编译器和整套构建本该在 x86_64 开发主机上执行,产物再部署到 ARM 目标机。厂商给出的标准流程是在 x86_64 Linux 主机上:

bash
export PATH=/opt/toolchains/gcc-11.3/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu/bin:$PATH
make TARGET_PLATFORM=aarch64-none-linux-gnu all

即配置好目标平台的交叉工具链后指定 TARGET_PLATFORM 一次构建,不同目标环境换对应 toolchain。这也是嵌入式开发的通用做法:目标机上凑工具链,不如在主机上交叉编译。

要点 ​

  • Exec format error 先查二进制架构(file 命令),发行包「面向某目标平台」不等于其附带的 host 工具能在该平台运行;
  • GLIBC_x.y not found 说明二进制要求的 glibc 高于系统版本,处理方向是换匹配的二进制或交叉编译,不是升系统 glibc;
  • 手工编译的 glibc 只能配合显式指定动态链接器按进程使用,替换 /lib 下的 libc 软链接会让全系统命令立刻段错误;
  • 数据库这类带代码生成器的 SDK,构建模型通常是 host/target 分离的,目标机直接 make 前先确认文档里对构建主机的假设。
最近更新

基于 VitePress 构建